﻿#region 文件信息

/*----------------------------------------------------------------
//
// 文件名称：
// 文件功能描述：
// 设计要求：
//
// 文 件 名：    LoginService
// 创建者：      杨程
// 创建日期：	    2022/12/20 17:46:49

//----------------------------------------------------------------*/

#endregion

namespace Vampirewal.Admin.Server.RpcServices.Service;

/// <summary>
/// 登陆服务
/// </summary>
public partial class LoginService : RpcServiceBasic
{

    private SystemService SysService { get; set; }

    private IVampirewalCoreEventBusFactory EventBusFactory { get; set; }

    /// <summary>
    ///
    /// </summary>
    public LoginService(SystemService sysService, IVampirewalCoreEventBusFactory _EventBusFactory)
    {
        SysService = sysService;
        EventBusFactory = _EventBusFactory;
        //构造函数

    }

    /// <summary>
    /// 登陆
    /// </summary>
    /// <param name="UserId">账号</param>
    /// <param name="PassWord">密码</param>
    /// <param name="callContext">上下文</param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    [Description("登陆")]
    [TouchRpc(MethodFlags = MethodFlags.IncludeCallContext)]
    public Sys_User Login(ICallContext callContext, string UserId, string PassWord)
    {
        var httpclient = callContext.Caller as HttpTouchRpcSocketClient;

        if (string.IsNullOrEmpty(UserId) || string.IsNullOrEmpty(PassWord))
        {
            throw new Exception("账号或密码为空！");
        }

        var user = SqlSugarRepository<Sys_User>().Single(f => f.UserId == UserId && f.Password == PassWord && f.State == 0);

        if (user != null)
        {
            if (SysService.CheckTenant(user.TenantId))
            {
                user.IpPort = httpclient.GetIPPort();
                user.LastLoginTime = DateTime.Now;
                user.IsOnline = true;

                httpclient?.ResetID(JsonConvert.SerializeObject(user));
                VampirewalCoreContext.GetInstance().AddContext($"{user.BillId}-httpclient", httpclient);
                                
                EventBusFactory.Publish("RpcLoginEvent", user);
                VampirewalCoreContext.GetInstance().AddContext(user.BillId, user);
                return user;
            }
            else
            {
                throw new Exception("该机构已到期，请联系对应管理员处理！");
            }
        }

        throw new Exception("未找到该用户的信息！");
    }

    /// <summary>
    /// 修改密码
    /// </summary>
    /// <param name="callContext">RPC上下文</param>
    /// <param name="OldPassWord">旧密码</param>
    /// <param name="NewPassWord">新密码</param>
    /// <returns></returns>
    [Description("修改密码")]
    [TouchRpc(MethodFlags = MethodFlags.IncludeCallContext)]
    [ActionFilter]
    public bool ChangePassWord(ICallContext callContext, string OldPassWord, string NewPassWord)
    {
        callContext.CheckCaller(out Sys_User user);

        var repUser = SqlSugarRepository<Sys_User>();

        var OldUser = repUser.Single(f => f.BillId == user.BillId);

        try
        {
            if (OldUser != null && OldUser.Password == OldPassWord)
            {
                OldUser.Password = NewPassWord;

                repUser.CurrentBeginTran();

                repUser.AsUpdateable(OldUser).WhereColumns(w => new { w.BillId }).UpdateColumns(u => new { u.Password }).ExecuteCommand();

                repUser.CurrentCommitTran();

                return true;
            }
            else
            {
                //throw new Exception("旧密码不正确!");

                return false;
            }
        }
        catch
        {
            repUser.CurrentRollbackTran();
            return false;
        }
    }

    /// <summary>
    /// 登出
    /// </summary>
    /// <param name="callContext"></param>
    /// <returns></returns>
    [Description("登出")]
    [TouchRpc(MethodFlags = MethodFlags.IncludeCallContext)]
    [ActionFilter]
    public bool LoginOut(ICallContext callContext)
    {
        callContext.CheckCaller(out Sys_User user);
        user.IsOnline = false;
        VampirewalCoreContext.GetInstance().RemoveContext(user.BillId);
        EventBusFactory.Publish("RpcLoginEvent", user);

        return VampirewalCoreContext.GetInstance().RemoveContext(user.BillId);
    }
}